N°9144 Add data audit setup step#801
Conversation
…ead of data audit, Catch exception during compilation to exit maintenance mode
There was a problem hiding this comment.
Pull request overview
This PR refactors the setup wizard into dedicated step classes and adds a new “data audit / compatibility check” step during upgrade, backed by a new step-based installation/audit sequencer.
Changes:
- Split wizard step logic into individual
setup/wizardsteps/*classes and updateWizardControllerto use them (UpdateWizardStateAndGetNextStep). - Add a new upgrade-only wizard step (
WizStepDataAudit) that runs a dry-run compilation + audit viaDataAuditSequencer. - Introduce
StepSequencer+ApplicationInstallSequencerinfrastructure and update unattended install to use it.
Reviewed changes
Copilot reviewed 33 out of 35 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| setup/wizardsteps/WizardStep.php | New base class for wizard steps (+ dependency checking helper). |
| setup/wizardsteps/WizStepWelcome.php | New welcome step implementation. |
| setup/wizardsteps/WizStepInstallOrUpgrade.php | New install/upgrade selection step implementation. |
| setup/wizardsteps/WizStepDetectedInfo.php | New upgrade-detection step (chooses license vs misc params). |
| setup/wizardsteps/WizStepLicense.php | New license step (incl. GDPR consent gating). |
| setup/wizardsteps/WizStepLicense2.php | Upgrade-specific license step. |
| setup/wizardsteps/WizStepDBParams.php | New DB params step implementation. |
| setup/wizardsteps/WizStepAdminAccount.php | New admin account step implementation. |
| setup/wizardsteps/AbstractWizStepMiscParams.php | Shared misc params helpers (symlink + force-uninstall flags). |
| setup/wizardsteps/WizStepInstallMiscParams.php | New install misc params step (URL/graphviz/sample data). |
| setup/wizardsteps/WizStepUpgradeMiscParams.php | New upgrade misc params step (URL/graphviz + force-uninstall). |
| setup/wizardsteps/WizStepModulesChoice.php | Module/extension selection step; routes to DataAudit on upgrade. |
| setup/wizardsteps/WizStepDataAudit.php | New compatibility check step (runs audit sequencer before Summary). |
| setup/wizardsteps/WizStepSummary.php | New summary step (now also includes backup option on upgrade). |
| setup/wizardsteps/WizStepInstall.php | Install/upgrade execution step using sequencer + progress UI. |
| setup/wizardsteps/WizStepDone.php | Final step (backup download + hub iframe + enter iTop button). |
| setup/wizardcontroller.class.inc.php | Loads new step files, switches to UpdateWizardStateAndGetNextStep, and respects CanComeBack(). |
| setup/wizard.php | Removes legacy wizardsteps.class.inc.php include. |
| setup/ajax.dataloader.php | Removes legacy wizardsteps.class.inc.php include (relies on controller includes). |
| setup/unattended-install/unattended-install.php | Uses ApplicationInstallSequencer for unattended installs. |
| setup/unattended-install/InstallationFileService.php | Removes legacy wizardsteps.class.inc.php include. |
| setup/setup.js | Minor formatting changes to button update logic. |
| setup/sequencers/StepSequencer.php | New base sequencer with ExecuteAllSteps() loop. |
| setup/sequencers/ApplicationInstallSequencer.php | New main install/upgrade sequencer (split out of old installer). |
| setup/sequencers/DataAuditSequencer.php | New dry-run compile + audit + cleanup sequencer for compatibility checks. |
| setup/applicationinstaller.class.inc.php | Reduced to compatibility wrapper (class_alias) pointing to sequencer. |
| setup/SetupDBBackup.php | Moves SetupDBBackup out of old installer into its own file. |
| setup/runtimeenv.class.inc.php | Minor formatting fix. |
| setup/feature_removal/get_model_reflection.php | Disables MetaModel cache in reflection script. |
| setup/feature_removal/SetupAudit.php | Forces model reflection loading for both envs. |
| setup/feature_removal/ModelReflectionSerializer.php | Adjusts command invocation + error message. |
| css/setup.scss | Makes installation progress visible (removes forced display:none). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| IssueLog::Info(__METHOD__, null, ['env' => $sEnv]); | ||
| $sPHPExec = trim(utils::GetConfig()->Get('php_path')); | ||
| $sOutput = ""; | ||
| $iRes = 0; | ||
|
|
||
| exec(sprintf("$sPHPExec %s/get_model_reflection.php --env='%s'", __DIR__, $sEnv), $sOutput, $iRes); | ||
| $sCommandLine = sprintf("$sPHPExec %s/get_model_reflection.php --env=%s", __DIR__, $sEnv); | ||
| exec($sCommandLine, $sOutput, $iRes); | ||
| if ($iRes != 0) { | ||
| $this->LogErrorWithProperLogger("Cannot get classes", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]); | ||
| throw new CoreException("Cannot get classes"); | ||
| throw new CoreException("Cannot get classes from env ".$sEnv); | ||
| } |
There was a problem hiding this comment.
GetModelFromEnvironment() builds a shell command using $sPHPExec (from config) and $sEnv without shell escaping, then executes it via exec(). This is vulnerable to command injection if either value contains spaces or shell metacharacters. Build the command using escapeshellcmd() / escapeshellarg() (or better, bypass the shell entirely) before calling exec().
There was a problem hiding this comment.
@Timmy38 not sure, but this could actually be a solution to the issue you had with quotes on Linux vs Windows.
| } | ||
|
|
||
| if (isset($aChoice['sub_options'])) { | ||
| $aScores[$sChoiceId] = array_merge($aScores[$sChoiceId], $this->GuessDefaultsFromModules($aChoice['sub_options'], $aDefaults, $sChoiceId)); | ||
| } |
There was a problem hiding this comment.
In GuessDefaultsFromModules(), the recursive call for sub_options passes $sChoiceId as the $aModules argument (GuessDefaultsFromModules(..., $sChoiceId)). This will break module lookup ($aModules[$sModuleId]...) and can cause runtime errors when a choice has sub_options. Pass the $aModules array and $sChoiceId as the parent id instead.
Hipska
left a comment
There was a problem hiding this comment.
I was wondering what exactly get's audited, it's not clear by reading the code.
I was also wondering if these audits are extendible by means of extensions.
Also, some suggestions that can picked up while doing this refactoring of wizard steps.
|
|
||
| use Combodo\iTop\Setup\FeatureRemoval\SetupAudit; | ||
|
|
||
| class DataAuditSequencer extends ApplicationInstallSequencer |
There was a problem hiding this comment.
overall remark. you add 2 sequencer. why not adding tests to make sure setup automata is what was designed. and to help the team see the sequence easily?
There was a problem hiding this comment.
if we could test the setup sequence without executing all complex steps(mocking). it could nice.
There was a problem hiding this comment.
A new StepSequencerTest class has been added and uses mock versions of both sequencers
setup/wizardsteps/WizardStep.php
Outdated
| * @param bool $bMoveForward True if the wizard is moving forward 'Next >>' button pressed, false otherwise | ||
| * @return hash array('class' => $sNextClass, 'state' => $sNextState) | ||
| */ | ||
| abstract public function UpdateWizardStateAndGetNextStep($bMoveForward = true); |
There was a problem hiding this comment.
return an array is ok. an object would be nicer here. to type the 2 elements. WizardState for ex.
setup/wizardcontroller.class.inc.php
Outdated
| $aNextStepInfo = $oStep->ProcessParams(true); // true => moving forward | ||
| $aNextStepInfo = $oStep->UpdateWizardStateAndGetNextStep(true); // true => moving forward | ||
| if (in_array($aNextStepInfo['class'], $aPossibleSteps)) { | ||
| $oNextStep = new $aNextStepInfo['class']($this, $aNextStepInfo['state']); |
There was a problem hiding this comment.
it could be nice to check the type of 'class' value before instanciation. also adding type.
There was a problem hiding this comment.
A new method GetWizardStep check that the next step is a subclass of WizardStep
| if ($oStep->CanComeBack()) { | ||
| $this->PushStep(['class' => $sCurrentStepClass, 'state' => $sCurrentState]); | ||
| } | ||
| $aPossibleSteps = $oStep->GetPossibleSteps(); |
There was a problem hiding this comment.
GetPossibleSteps seems useless to me. unless we keep it to test setup automata and use DumpXXX somewhere.
setup/wizardcontroller.class.inc.php
Outdated
| @@ -169,7 +195,7 @@ protected function Back() | |||
| $sCurrentStepClass = utils::ReadParam('_class', $this->sInitialStepClass); | |||
| $sCurrentState = utils::ReadParam('_state', $this->sInitialState); | |||
| $oStep = new $sCurrentStepClass($this, $sCurrentState); | |||
There was a problem hiding this comment.
it could be nice to check the type before instanciation. also adding type afterwhile (@var XXX varname).
There was a problem hiding this comment.
Same as above about GetWizardStep (with typing)
odain-cbd
left a comment
There was a problem hiding this comment.
lot of changes in setup wizard. but no test coverage of the controller/automata to make sure we are ok with sequence(s). it would be nice to add some test(s) and help the team figure out the sequence.
test would garantee the result and reduce end 2 end validation from a browser...
No description provided.